﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace Economo.Services.DataContext
{
    public class CreditCardDataContext : IDisposable 
    {                        
         DataClassesDataContext _context = new DataClassesDataContext(ConfigurationManager.ConnectionStrings["Economo"].ConnectionString);

        public List<CreditCard> GetCreditCards()
        {
            try
            {
                var cards = from c in _context.CreditCards
                               orderby c.BankId, c.Id
                               select c;
                List<CreditCard> result = new List<CreditCard>(cards);
                return result;
            }
            catch (Exception ex)
            {
                ExceptionHandling.ManageExceptions.ManageDataAccessException(new ExceptionHandling.DataAccessException("Error getting credit cards", ex));
                return null;
            }
        }

        public List<CreditCard> GetCreditCards(byte bankId)
        {
            try
            {
                var cards = from c in _context.CreditCards
                               where c.BankId == bankId
                               orderby c.Id
                               select c;
                List<CreditCard> result = new List<CreditCard>(cards);
                return result;
            }
            catch (Exception ex)
            {
                ExceptionHandling.ManageExceptions.ManageDataAccessException(new ExceptionHandling.DataAccessException("Error getting credit cards", ex));
                return null;
            }

        }



        public CreditCard GetCardById(byte bankId, byte cardId)
        {
            try
            {
                CreditCard card = (from c in _context.CreditCards
                                       where c.BankId == bankId && c.Id == cardId
                                    select c).FirstOrDefault<CreditCard>();
                return card;

            }
            catch (Exception ex)
            {
                ExceptionHandling.ManageExceptions.ManageDataAccessException(new ExceptionHandling.DataAccessException("Error getting credit card by id", ex));
                return null;
            }
        }
        public CreditCard GetCardById(byte cardId)
        {
            try
            {
                CreditCard card = (from c in _context.CreditCards
                                   where c.Id == cardId
                                   select c).FirstOrDefault<CreditCard>();
                return card;

            }
            catch (Exception ex)
            {
                ExceptionHandling.ManageExceptions.ManageDataAccessException(new ExceptionHandling.DataAccessException("Error getting credit card by id", ex));
                return null;
            }
        }

        public byte Insert(CreditCard newCreditCard)
        {
            try
            {
                InsertCreditCardResult result = _context.InsertCreditCard(newCreditCard.BankId, newCreditCard.Description, newCreditCard.CardNumber, newCreditCard.Expiration,newCreditCard.SecurityCode,newCreditCard.Picture ).FirstOrDefault<InsertCreditCardResult>();
                if (result.Id.HasValue)
                    return result.Id.Value;
                else
                    throw new ExceptionHandling.DataAccessException("Impossible to retrieve autogenerated id when inserting new row");
            }
            catch (Exception ex)
            {
                ExceptionHandling.ManageExceptions.ManageDataAccessException(new ExceptionHandling.DataAccessException("Error inserting new credit card", ex));
                return 0;
            }            
        }

        public void Update(CreditCard card)
        {
            try
            {
                CreditCard updated = (from c in _context.CreditCards 
                                       where c.BankId == card.BankId && c.Id == card.Id
                                       select c).First();
                if (updated != null)
                {                    
                    updated.Description = card.Description;
                    updated.CardNumber = card.CardNumber;
                    updated.Expiration = card.Expiration;
                    updated.SecurityCode = card.SecurityCode;
                    updated.Picture = card.Picture;
                    _context.SubmitChanges(System.Data.Linq.ConflictMode.FailOnFirstConflict);
                }
                else
                    throw new ExceptionHandling.DataAccessException("Credit card not found with Id=" + card.Id.ToString());
            }
            catch (Exception ex)
            {
                ExceptionHandling.ManageExceptions.ManageDataAccessException(new ExceptionHandling.DataAccessException("Error updating credit card", ex));
            }
        }
        public void Delete(CreditCard card)
        {
            try
            {
                _context.CreditCards.DeleteOnSubmit(card);
                _context.SubmitChanges(System.Data.Linq.ConflictMode.FailOnFirstConflict);
            }
            catch (Exception ex)
            {
                ExceptionHandling.ManageExceptions.ManageDataAccessException(new ExceptionHandling.DataAccessException("Error deleting credit card", ex));
            }
        }
        public void Delete(byte bankId, byte cardId)
        {
            try
            {
                CreditCard card = GetCardById(bankId, cardId);
                if (card != null)
                    Delete(card);
                else
                    throw new ExceptionHandling.DataAccessException("Card to delete not found");
            }
            catch (Exception ex)
            {
                ExceptionHandling.ManageExceptions.ManageDataAccessException(new ExceptionHandling.DataAccessException("Error deleting credit card", ex));
            }
        }



        public void Dispose()
        {
            if (_context!=null)
                _context.Dispose();
        }

    }
}
